﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class UtilsDraw
{
    public delegate void SetPixel (int x, int y, Color color);
    public static void DrawLine(SetPixel setPixel, Texture2D texture, Vector3 startPos, Vector3 endPos, Color color)
    {
        var drawLine = endPos - startPos;
        int lineM = 0;
        if (Mathf.Abs(drawLine.x) > Mathf.Abs(drawLine.y))
            lineM = (int)Mathf.Abs(drawLine.x) + 1;
        else
            lineM = (int)Mathf.Abs(drawLine.y) + 1;
        for (int i = 0; i < lineM; ++i)
        {
            float scale = (lineM - i) / (float)lineM;
            var newY = Mathf.Clamp(startPos.y + (drawLine.y * scale), 0, texture.height);
            var newX = Mathf.Clamp(startPos.x + (drawLine.x * scale), 0, texture.width);

            setPixel((int)newX, (int)newY, color);
        }
    }
    public static void DrawLine(Texture2D texture, Vector3 startPos, Vector3 endPos, Color color)
    {
        DrawLine(texture.SetPixel, texture, startPos, endPos, color);
    }

    /// <summary>
    /// make full for a area of texture
    /// </summary>
    /// <param name="texture">the texutre you want to full</param>
    /// <param name="x">the start point of full</param>
    /// <param name="y">the start point of full</param>
    /// <param name="fullColor">the color will be replaced by full operation</param>
    /// <param name="newColor">the new color will replace the oldColor</param>
    public static void FullColor(Texture2D texture, int x, int y, Color fullColor, Color newColor)
    {
        if (IsEqupmentColor(fullColor, newColor))
            return;
        Queue<Vector2Int> m_FullQueue = new Queue<Vector2Int>();
        m_FullQueue.Enqueue(new Vector2Int(x, y));
        int count = 0;
        while (m_FullQueue.Count > 0)
        {
            var tureData = m_FullQueue.Dequeue();
            var colorInTexture = texture.GetPixel(tureData.x, tureData.y);
            if (tureData.x > 0 && tureData.y > 0 &&
                tureData.x < texture.width && tureData.y < texture.height &&
                IsEqupmentColor(texture.GetPixel(tureData.x, tureData.y), fullColor))
            {
                texture.SetPixel(tureData.x, tureData.y, newColor);

                m_FullQueue.Enqueue(new Vector2Int(tureData.x + 1, tureData.y));
                m_FullQueue.Enqueue(new Vector2Int(tureData.x - 1, tureData.y));
                m_FullQueue.Enqueue(new Vector2Int(tureData.x, tureData.y + 1));
                m_FullQueue.Enqueue(new Vector2Int(tureData.x, tureData.y - 1));
            }
            count++;
        }
    }
    public static bool IsEqupmentColor(Color color1, Color color2)
    {
        if (Mathf.Abs(color1.r - color2.r) < 0.0039f &&
                Mathf.Abs(color1.g - color2.g) < 0.0039f &&
                Mathf.Abs(color1.b - color2.b) < 0.0039f &&
                Mathf.Abs(color1.a - color2.a) < 0.0039f)
        {
            return true;
        }
        return false;
    }
}